(function () {
	//在body里面注册全局事件
	//点击任何地方,都关闭panel
	$(window.document).click(function(event){
		var element = PickerUtils.getTarget(event);
		var targetPickerDiv = $(element).closest(".Picker");
		$(".Picker .Panel").each(function(i , n){
			var hiddenPicker = $(this).closest(".Picker");
			if(targetPickerDiv.data("obj") != hiddenPicker.data("obj")){
				$(this).hide();
				$(this).prev().removeClass('open');
			}
		});
	});

	var AbstractPicker, SimplePicker, TablePicker, TreePicker, PickerUtils;
	PickerUtils = {
		copyProperty: function(toObj, fromObj) {
			for ( var key in fromObj) {
				toObj[key] = fromObj[key];
			}
		},
		//类的继承,不但会继承方法,属性也会继承
		extend: function(child, parent) {
			this.copyProperty(child, parent);
			function ctor() {
				this.constructor = child;
			}
			ctor.prototype = parent.prototype;
			child.prototype = new ctor();
			child.__super__ = parent.prototype;
			return child;
		},
		bind: function(fn, me) {
			return function() { return fn.apply(me, arguments); };
		},
		//返回事件的实际目标
		getTarget: function(ev) {
			return ev.target || ev.srcElement;
		},
		//阻止事件的默认行为
		preventDefault: function(ev){
			if(ev.preventDefault){
				ev.preventDefault(); 
			}else{
				ev.returnValue=false;
			}
		}, 
		//立即停止事件在DOM中的传播
		stopPropagation: function(ev){ 
			//避免触发注册在document.body上面的事件处理程序
			if(ev.stopPropagation){
				ev.stopPropagation();
			}else{
				ev.cancelBubble=true;
			}
		}
	};

	/**
	 * picker的基类
	 * 用于定义基本的picker框架
	 * 定义基本的picker的方法和属性配置
	 * 
	 * dom结构如下
	 * <div class="Picker">
	 * 	<input type="hidden" name="option.name"/>
	 * 	<div class="selectBox form-control">
	 * 		<ul class="selectText">
	 * 			<li></li>
	 * 		</ul>
	 * 		
	 * 		<div class="selectButton">
	 * 
	 * 		</div>
	 * 	</div>
	 * 	<div class="Panel">
	 * 		<div class="filter"><input></div>
	 * </div>
	 * </div>
	 * 
	 * 接受数据格式
	 * [{
	 * id:"", pid:"" , value:"" , name:""
	 * }]
	 * 
	 */
	AbstractPicker = (function () {
		function AbstractPicker(_option){
			this.option = {
				name: null,									//表单提交的字段名称
				defaultValue: null,					//页面渲染时的默认值
				data: [],									  //本地数据
				url: "",
				urlData: {},
				separetor: ',',
				convertData: {},					  //远程或者本地data的转换
				mode: "single",						  //single:单选,multi:多选
				type: 'simple',             //simple, tree, table
				columns: [],                //当type=table时有效
				filter: false,
				onfilter: {},								//过滤的回调函数,返回过滤的数据列表,如果还有convertData函数会onfilter的时候会被调用
				onselect: {}
			}
			PickerUtils.copyProperty(this.option, _option || {});

			//私有变量需要定义在function内部
			this.pickerDiv = $("<div>").addClass("Picker").data("obj" , this);
			this.submitField = $("<input type='hidden' id='"+this.option.name+"' name='"+this.option.name+"'/>");	
			this.pickerDiv.append(this.submitField);
			this.selectBox = $("<div>").addClass("selectBox");
			this.selectText = $("<ul>").addClass("selectText");
			this.pickerDiv.append(this.selectBox.append(this.selectText));
			
			this.panelDiv = $("<div>").addClass("Panel");
			this.pickerDiv.append(this.panelDiv);
			/**
			 * 注册事件
			 * 事件需要使用到this指针,指向当前的对象,需要使用bind方法进行包装和转化
			 */
			this.selectBox.click(
				PickerUtils.bind(function(){
					this.togglePanel();
				},this)
			);

			if(this.option.filter && this.option.abstractype == 'simple'){
				var filterInput = $("<input>").attr("type","text").addClass("filter-input");
				this.panelDiv.append(filterInput);

				var filterTimeOut;
				var filterFunction = PickerUtils.bind(function(){
					if($.isFunction(this.option.onfilter)){
						var _filterData = this.option.onfilter.call(this , $(filterInput).val());
						if($.isFunction(this.option.convertData)){
							_filterData = this.option.convertData.call(this , _filterData);
						}
					}else{
						if(this.filterData){
							this.filterData($(filterInput).val());
						}
					}
					clearInterval(filterTimeOut);
				} , this);
				filterInput.keyup(function(){
					if(filterTimeOut){
						clearInterval(filterTimeOut);
						filterTimeOut = null;
					}
					filterTimeOut = setTimeout( filterFunction, 300);
					
				}
				);
			}

			this.dataDiv = $("<div>").addClass("dataDiv");
			this.panelDiv.append(this.dataDiv);

			var data = this.option.data = this.fetchData();
			this.renderData(data);
		}
		
		AbstractPicker.prototype.showPanel = function(){
			$(this.panelDiv).show();
			$(this.selectBox).addClass('open');
		}

		AbstractPicker.prototype.hidePanel = function(){
			$(this.panelDiv).hide();
			$(this.selectBox).removeClass('open');
		}

		AbstractPicker.prototype.togglePanel = function(){
			var status= $(this.panelDiv).is(":visible");
			if(status){
				this.hidePanel();
			}else{
				this.showPanel();
			}
		}

		AbstractPicker.prototype.setText = function(setText){
			$(this.selectBox).text(setText);
		}

		AbstractPicker.prototype.setValue = function(setValue){
			$(this.submitField).val(setValue);
		}

		AbstractPicker.prototype.getValue = function(){
			return $(this.submitField).val();
		}

		/**
		 * data , 所有选中的数据
		 */
		AbstractPicker.prototype.selectItem = function(data){
			var valueArr = [];
			var textArr = [];
			$.each(data , function(i , n){
				valueArr.push(n.value);
				textArr.push(n.name);
			});
			this.setValue(valueArr.join(this.option.separetor));
			this.setText(textArr.join(this.option.separetor));

			if($.isFunction(this.option.onselect)){
				this.option.onselect.call(this , data);
			}
		}

		/**
		 * 对外的渲染方法
		 * 得到整个选择器的dom
		 */
		AbstractPicker.prototype.outHTML = function () {
			return this.pickerDiv;
		}

		AbstractPicker.prototype.renderTo = function (el) {
			$(el).append(this.outHTML());
			//渲染之后,才有width
			this.panelDiv.outerWidth(this.pickerDiv.outerWidth());
		}

		/**
		 * 获取数据
		 * 使用配置的option.data,进行转化
		 * 如果没有配置option.data,使用url获取,并进行转化
		 */
		AbstractPicker.prototype.fetchData = function(){
			if(this.option.data){
				if($.isFunction(this.option.convertData)){
					return this.option.convertData.call(this , this.option.data);
				}
				return this.option.data;
			}else if(this.option.url){
				var result = null;
				$.post(url , this.option.urlData , function(data){
					result = this.option.convertData.call(this , data);
				},"json");
				return result;
			}
		}

		return AbstractPicker;
	})();

	/**
	 * 简单的下拉选择
	 * 
	 */
	SimplePicker = (function(superClass){
		/**
		 * 继承父类方法
		 */
		PickerUtils.extend(SimplePicker, superClass);
		function SimplePicker(_option){
			var option = {abstractype: 'simple'};
			PickerUtils.copyProperty(option, _option || {});
			SimplePicker.__super__.constructor.call(this, option);
		}

		//渲染数据的方法
		//每个picker子类都需要实现的方法
		SimplePicker.prototype.renderData = function(data){
			$.each(data, PickerUtils.bind(function(i, n){
				var button = $("<div>").addClass("itemButton").addClass(this.option.mode);
				var name = $("<div>").addClass("itemText").text(n.name).attr("value",n.value);
				var panelItem = $("<div>").addClass("panelItem");
				panelItem.data("data" , n);
				panelItem.append(button).append(name);
				this.dataDiv.append(panelItem);

				panelItem.click(PickerUtils.bind(function(event){
					if(this.option.mode == "single"){
						$(".itemButton" , this.dataDiv).removeClass("checked");
					}
					if(button.hasClass("checked")){
						button.removeClass("checked");
					}else{
						button.addClass("checked");
					}

					var dataList = [];
					$(".itemButton.checked" , this.dataDiv).each(function(index , itemButton){
						var item = $(itemButton).parent();
						dataList.push(item.data("data"));
					});

					this.selectItem(dataList);

					//对于多选组件来说,选择其中的选项的时候,不用对外进行事件冒泡,避免过多的冒泡导致panel展示不正确
					PickerUtils.stopPropagation(event);
				},this));
			},this));

			this.setData(this.option.defaultValue);
		}

		SimplePicker.prototype.setData = function(setValue) {
			if(setValue){
				var selectList = [];
				var valArr = setValue.split(this.option.separetor);
				if(this.option.mode === 'single') valArr = [valArr[0]];

				$(".panelItem" , this.dataDiv).each(function(index , panelItem){
					var data = $(panelItem).data("data");
					if(valArr.indexOf(data.value) >= 0) {
						$(panelItem.children[0]).addClass('checked');
						selectList.push(data);
					} else {
						$(panelItem.children[0]).removeClass('checked');
					}
				});
				this.selectItem(selectList);
			}
		}

		/**
		 * 过滤的方法
		 * 所有的下拉都必须实现
		*/
		SimplePicker.prototype.filterData = function(data){
			$(".panelItem" , this.dataDiv).show();

			if(data){
				var escapedQuery = data.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
				var regx = new RegExp("^(^|\\s|\\b)" + escapedQuery + "[^\\s]*");
				$(".panelItem" , this.dataDiv).each(PickerUtils.bind(function(i , n){
					var text = $(".itemText" , n).text();
					if(!regx.test(text)){
						$(n).hide();
					}
				},this));
			}
		}

		return SimplePicker;
	})(AbstractPicker);

	TreePicker = (function(superClass){
		PickerUtils.extend(TreePicker, superClass);
		function TreePicker(_option){
			var option = {abstractype: 'tree'};
			PickerUtils.copyProperty(option, _option || {});
			TreePicker.__super__.constructor.call(this, option);
		}

		TreePicker.prototype.renderData = function(data){
			var that = this;
			var setting = {
				check: {
					enable: true,
					chkboxType: this.option.mode === 'multi' ? {"Y":"", "N":""} : undefined,
					chkStyle: this.option.mode === 'single' ? "radio" : undefined,
					radioType: this.option.mode === 'single' ? "all" : undefined
				},
				view: {
					dblClickExpand: false
				},
				data: {
					simpleData: {
						enable: true
					}
				},
				callback: {
					onCheck: onCheck,
					onClick: onClick,
				}
			};
			function onClick(e, treeId, treeNode) {
				var zTree = $.fn.zTree.getZTreeObj(treeId);
				zTree.checkNode(treeNode, !treeNode.checked, null, true);
				return false;
			}
			
			function onCheck(e, treeId, treeNode) {
				var zTree = $.fn.zTree.getZTreeObj(treeId);
				nodes = zTree.getCheckedNodes(true);
				that.selectItem(nodes);
			}
			this.dataDiv.addClass('ztree').attr('id', 'ztreeid' + parseInt(Math.random() * 1000));
			this.setDefaultData(this.option.defaultValue, data);
			this.zTree = $.fn.zTree.init(this.dataDiv, setting, data);
		}

		TreePicker.prototype.setDefaultData = function(setValue, data) {
			if(setValue){
				var selectList = [];
				var valArr = setValue.split(this.option.separetor);
				if(this.option.mode === 'single') valArr = [valArr[0]];
				$.each(data, function(i, item) {
					if(valArr.indexOf(item.value) > -1) {
						item.checked = true;
						selectList.push(item);
					}
				})
				this.selectItem(selectList);
			}
		}
		return TreePicker;
	})(AbstractPicker);

	TablePicker = (function(superClass){
		PickerUtils.extend(TablePicker, superClass);
		function TablePicker(_option){
			var option = {abstractype: 'table'};
			PickerUtils.copyProperty(option, _option || {});
			TablePicker.__super__.constructor.call(this, option);
		}

		TablePicker.prototype.renderData = function(data){
			var columns = [], that = this;
			var percent = (1 / this.option.columns.length) * 100 + '%';
			this.option.columns.forEach(function(column) {
				columns.push({data: column.key, title: column.title, width: column.width || percent});
			});
			this.panelDiv.css({height: '300px'})
			this.dataTable = $('<table class="display"></table>');
			this.dataDiv.append(this.dataTable);
			var table = this.table = $(this.dataTable).DataTable({
				"data": data,
				"columns": columns,
				"autoWidth": false,
				"pagingType": 'full',
				"paging": false,
				"info": false,
				"searching": this.option.filter || false,
				"language": {
						"zeroRecords": "没有找到记录"
				}
				
			});
			this.dataTable.find('tbody').on('click', 'tr', function() {
				if(that.option.mode === 'single') {
					if ( $(this).hasClass('selected') ) {
						$(this).removeClass('selected');
					}
					else {
						table.$('tr.selected').removeClass('selected');
						$(this).addClass('selected');
					}
				} else if(that.option.mode === 'multi') {
					$(this).toggleClass('selected');
				}
				
				var selected = table.rows('.selected').data();
				var l = table.rows('.selected').data().length;
				var sdata = [];
				while(l > 0) {
					l -= 1;
					sdata.push(selected[l]);
				}
				that.selectItem(sdata);
			})
			this.setData(this.option.defaultValue);
		}

		TablePicker.prototype.setData = function(setValue) {
			if(setValue){
				var selectList = [];
				var valArr = setValue.split(this.option.separetor);
				if(this.option.mode === 'single') valArr = [valArr[0]];

				var nodes = this.table.rows().nodes();
				var datas = nodes.data();
				var l = nodes.length;
				while(l > 0) {
					l -= 1;
					if(valArr.indexOf(datas[l].value) > -1) {
						$(nodes[l]).addClass('selected');
						selectList.push(datas[l]);
					} else {
						$(nodes[l]).removeClass('selected');
					}
				}
				
				this.selectItem(selectList);
			}
		}
		return TablePicker;
	})(AbstractPicker);

	/**
	 * 暴露jquery的访问方式
	 */
	$.fn.SimplePicker = function (_option) {
		var picker =  new SimplePicker(_option);
		picker.renderTo($(this));
		return picker;
	}
	$.fn.TreePicker = function (_option) {
		var picker =  new TreePicker(_option);
		picker.renderTo($(this));
		return picker;
	}
	$.fn.TablePicker = function (_option) {
		var picker =  new TablePicker(_option);
		picker.renderTo($(this));
		return picker;
	}
})();
